package com.muyu.payment.util;

import com.muyu.common.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * 支付工具类
 */
public class PaymentUtils {

    private static final Logger log = LoggerFactory.getLogger(PaymentUtils.class);
    
    /**
     * 生成签名
     *
     * @param params 参数
     * @param key 密钥
     * @param signType 签名类型(MD5/RSA等)
     * @return 签名
     */
    public static String generateSign(Map<String, String> params, String key, String signType) {
        // 过滤空值
        Map<String, String> filteredParams = new HashMap<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (StringUtils.isNotBlank(entry.getValue()) && !"sign".equals(entry.getKey())) {
                filteredParams.put(entry.getKey(), entry.getValue());
            }
        }
        
        // 按参数名ASCII码从小到大排序
        List<String> keys = new ArrayList<>(filteredParams.keySet());
        Collections.sort(keys);
        
        // 拼接参数
        StringBuilder sb = new StringBuilder();
        for (String k : keys) {
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(k).append("=").append(filteredParams.get(k));
        }
        
        // 拼接密钥
        sb.append("&key=").append(key);
        
        // 计算签名
        if ("MD5".equalsIgnoreCase(signType)) {
            return md5(sb.toString()).toUpperCase();
        } else if ("SHA256".equalsIgnoreCase(signType)) {
            return sha256(sb.toString()).toUpperCase();
        } else {
            throw new IllegalArgumentException("不支持的签名类型：" + signType);
        }
    }
    
    /**
     * 验证签名
     *
     * @param params 参数
     * @param key 密钥
     * @param signType 签名类型
     * @return 是否验证通过
     */
    public static boolean verifySign(Map<String, String> params, String key, String signType) {
        String sign = params.get("sign");
        if (StringUtils.isBlank(sign)) {
            return false;
        }
        
        String generatedSign = generateSign(params, key, signType);
        return sign.equals(generatedSign);
    }
    
    /**
     * MD5加密
     */
    public static String md5(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(digest);
        } catch (NoSuchAlgorithmException e) {
            log.error("MD5加密失败", e);
            return "";
        }
    }
    
    /**
     * SHA256加密
     */
    public static String sha256(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(digest);
        } catch (NoSuchAlgorithmException e) {
            log.error("SHA256加密失败", e);
            return "";
        }
    }
    
    /**
     * 字节数组转16进制字符串
     */
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) {
                sb.append('0');
            }
            sb.append(hex);
        }
        return sb.toString();
    }
    
    /**
     * 生成随机字符串
     *
     * @param length 字符串长度
     * @return 随机字符串
     */
    public static String generateRandomString(int length) {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
}
